package generic;

import java.util.ArrayList;

/**
 * @author DCSGO
 * @version 1.0
 * 泛型引入
 * 1.请编写程序，在ArrayList中，添加3个Dog对象
 * 2.Dog对象含有name和age，并输出name和age(要求使用getXxx())
 */

@SuppressWarnings({"all"})
public class Generic01 {
    //传统方式
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(new Dog("旺财", 4));
        arrayList.add(new Dog("阿福", 6));
        arrayList.add(new Dog("小花", 2));

        for (Object obj : arrayList) {
            Dog dog = (Dog) obj;
            System.out.println(dog.getName() + "-" + dog.getAge());
        }
        //旺财-4
        //阿福-6
        //小花-2

        //好像没啥问题 但要是在不经意间我们写出了如下代码
//        arrayList.add(new Cat("花花",3));
//        for (Object obj : arrayList) {
//            Dog dog = (Dog) obj;
//            System.out.println(dog.getName() + "-" + dog.getAge());
//        }
        //ClassCastException: generic.Cat cannot be cast to generic.Dog
        //抛出异常

        //使用传统方法的问题分析
        //1)不能对加入到集合 ArrayList 中的数据类型进行约束(不安全)
        //2)遍历的时候 需要进行类型转换 如果集合中的数据量较大 对效率有影响
        //泛型快速体验-用泛型来解决前面的问题

        ArrayList<Dog> Dogs = new ArrayList<Dog>();
        Dogs.addAll(arrayList);
        System.out.println(Dogs);
        //[Dog{name='旺财', age=4}, Dog{name='阿福', age=6}, Dog{name='小花', age=2}]

        //Dogs.add(new Cat("花花",3));
        //上面的代码直接编译不了
        //遍历时也可以直接使用 Dog 引用来直接接收了 不用再向下转型了
        for (Dog dog : Dogs) {
            System.out.println(dog.getName() + "-" + dog.getAge());
        }
        //旺财-4
        //阿福-6
        //小花-2

        //泛型的好处
        //1)编译时 检查添加元素的类型 提高了安全性
        //2)减少了类型转换的次数 提高效率：
        //若不使用泛型:
        //Dog ->Object -> Dog 放入到ArrayList
        //会先转成 Object 在取出时 还需要转换成 Dog
        //使用泛型:
        //Dog ->Dog -> Dog 放入时 和取出时 不需要类型转换 提高效率
        //3)不再会出现添加不同类型的元素后 运行时抛出异常 出现奇怪的 Bug
    }
}

class Dog {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

class Cat {
    private String name;
    private int age;

    public Cat(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
